package com.opencee.cloud.msg.thread.handler;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.opencee.cloud.msg.api.constatns.MsgContentType;
import com.opencee.cloud.msg.api.constatns.MsgLevel;
import com.opencee.cloud.msg.api.constatns.MsgPushPlatform;
import com.opencee.cloud.msg.api.entity.MsgMessageTemplateEntity;
import com.opencee.cloud.msg.api.entity.MsgTaskEmailRecordsEntity;
import com.opencee.cloud.msg.api.entity.MsgTaskPushRecordsEntity;
import com.opencee.cloud.msg.api.vo.MsgChannelConfigVO;
import com.opencee.cloud.msg.api.vo.params.MessageTaskParams;
import com.opencee.cloud.msg.api.vo.params.PushBatchParams;
import com.opencee.cloud.msg.api.vo.params.PushSingleParams;
import com.opencee.cloud.msg.config.MessageTaskContext;
import com.opencee.cloud.msg.service.MsgApplicationChannelService;
import com.opencee.cloud.msg.service.MsgPushSenderService;
import com.opencee.cloud.msg.service.MsgTaskPushRecordsService;
import com.opencee.cloud.msg.service.MsgTemplateService;
import com.opencee.cloud.msg.thread.MessageTaskHandler;
import com.opencee.common.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 消息推送适配器
 *
 * @author yadu
 */
@Slf4j
public class PushTaskHandler implements MessageTaskHandler, Serializable {

    private MsgTemplateService msgTemplateService;
    private MsgTaskPushRecordsService msgTaskPushRecordsService;
    private MsgApplicationChannelService msgApplicationChannelService;

    public PushTaskHandler() {
    }

    public PushTaskHandler(MsgTemplateService msgTemplateService, MsgTaskPushRecordsService msgTaskPushRecordsService,MsgApplicationChannelService msgApplicationChannelService) {
        this.msgTemplateService = msgTemplateService;
        this.msgTaskPushRecordsService = msgTaskPushRecordsService;
        this.msgApplicationChannelService = msgApplicationChannelService;
    }


    /**
     * 前置参数验证
     *
     * @param taskParams
     * @return
     */
    @Override
    public boolean validate(MessageTaskContext context, MessageTaskParams taskParams) throws RuntimeException {
        Object params = taskParams.getParams();
        if (params instanceof PushSingleParams) {
            PushSingleParams singleParams = (PushSingleParams) params;
            this.valid(context, singleParams, 0);
        } else {
            PushBatchParams batchParams = (PushBatchParams) params;
            List<PushSingleParams> batchList = batchParams.getBatchList();
            int size = batchList.size();
            for (int i = 0; i < size; i++) {
                PushSingleParams singleParams = batchList.get(i);
                this.valid(context, singleParams, i);
            }
        }
        return true;
    }

    @Override
    public boolean execute(MessageTaskContext context, MessageTaskParams taskParams) {
        List<MsgTaskPushRecordsEntity> recordList = new ArrayList<>();
        MsgPushSenderService pushSenderService = null;
        context.getVariable(VAR_CHANNEL_LIST,)
        try {
            MsgPushSenderService pushService = SpringContextHolder.getBean("push_"+channel.ge());
            if (pushService == null) {
                return false;
            }
            JSONObject props = channel.getContentObject();
            Object params = taskParams.getParams();
            if (params instanceof PushSingleParams) {
                PushSingleParams singleParams = (PushSingleParams) params;
                if (((PushSingleParams) params).getContentType())
                    pushService.pushByAlias(props, (PushSingleParams) params);
            } else {
                PushBatchParams batchParams = (PushBatchParams) params;
                batchParams.getBatchList().forEach(t -> {
                    pushSenderService.send(taskParams.getChannelConfig(), t);
                });
            }
            return true;
        } catch (Exception e) {
            log.error("推送消息错误:", e);
        } finally {
            // 保存发送日志
            MsgTaskPushRecordsEntity record = new MsgTaskPushRecordsEntity();
            record.setTaskId(taskParams.getTaskId());
            record.setAppId(taskParams.getAppId());
            record.setDelayedTime(taskParams.getDelayedTime());
            if (!CollectionUtil.isEmpty(textParams.getCc())) {
                record.setSendCc(CollectionUtil.join(textParams.getCc(), ";"));
            }
            record.setMsgId(textParams.getSubject());
            record.setErrorMessage(error);
            record.setCreateTime(new Date());
            record.setUpdateTime(record.getCreateTime());
            if (!recordList.isEmpty()) {
                msgTaskPushRecordsService.saveBatch(recordList);
            }
        }
        return false;
    }

    @Override
    public boolean support(Object message) {
        return message instanceof PushSingleParams || message instanceof PushBatchParams;
    }

    private void valid(MessageTaskContext context, PushSingleParams params, Integer index) {
        Assert.notNull(params.getLevel(), "level不能为空");
        Assert.notNull(params.getAppId(), "appId不能为空");
        Assert.notNull(params.getContentType(), "contentType不能为空");
        Assert.notEmpty(params.getPlatform(), "platform不能为空");
        Assert.isTrue(MsgLevel.isInclude(params.getLevel()), "level不匹配");
        Assert.isTrue(MsgContentType.isInclude(params.getContentType()), "contentType不匹配");
        for (Integer s : params.getPlatform()) {
            Assert.isTrue(MsgPushPlatform.isInclude(s), "platform不匹配");
        }
        if (MsgContentType.TEXT.equals(params.getContentType())) {
            Assert.hasText(params.getTitle(), "title不能为空");
            Assert.hasText(params.getContent(), "pushMode不能为空");
        } else {
            Assert.hasText(params.getTemplateCode(), "templateCode不能为空");
            MsgMessageTemplateEntity template = msgTemplateService.getByTplCode(params.getTemplateCode());
            context.setVariable("template" + index, template);
        }
    }
}
